import { ref, watch } from 'vue';
type ItemType = 'left' | 'right';

const useCarousel = <T>(props: any, _this: any, args?: T & any) => {
  /* 定义变量 */
  const subIndex = ref(0);
  const imgMap: any = ref({});  // 图片下标映射{ 0: '1.png' }
  const bannerElm = ref(null);
  const countDownTimer = ref(0);
  const imgWidth = ref(0);
  const subfixItems = ref<Array<HTMLElement>>([]);
  const subfixItemsInner = ref<Array<HTMLElement>>([]);

  /* 监听属性 */
  watch(() => props.images, (v, o) => {
    if (Array.isArray(v)) {
      v.forEach((img, i) => imgMap.value[i] = img);
    }    
  }, { immediate: true });

  // @ts-ignore
  const receiveBannerBox = (el: HTMLElement) => bannerElm.value = el;
  const receiveSubfixItem = (el: HTMLElement) => subfixItems.value.push(el);
  const receiveSubfixItemInner = (el: HTMLElement) => subfixItemsInner.value.push(el);

  // 切换图片(图片滚动)
  const imgRoll = (shiftNode?: Array<any>) => {
    let timer = setInterval(() => {
      // 最后一张
      imgWidth.value += 12;
      (bannerElm.value as any as HTMLElement).style.left = -imgWidth.value + 'px';
      // 切换完成的时候 重置left以及操作dom将第一个扔到最后一个去
      if (imgWidth.value === 0 || !(imgWidth.value % 900)) {
        // 删除第一项
        const removeNode = (bannerElm.value as any as HTMLElement).removeChild((bannerElm.value as any as HTMLElement).children[0]);
        (bannerElm.value as any as HTMLElement).appendChild(removeNode);
        // 如果是切换的话, 那么切换的图片最后添加到列表中
        if (shiftNode && shiftNode.length > 0) {
          [...shiftNode].forEach(el => {
            (bannerElm.value as any as HTMLElement).appendChild(el);
          })
        }
        (bannerElm.value as any as HTMLElement).style.left = '0px';
        imgWidth.value = 0;
        clearInterval(timer);
      }
    }, 10);
  }

  // 清空下标
  const clearSub = () => {
    const subfixInnerElms: any = document.getElementsByClassName('subfix-item-inner');
    [...subfixInnerElms].forEach((elm: HTMLElement) => (elm.style.width = '0%'));
  }

  // 切换下标
  const shiftSub = (index: number) => {
    /**
     * 下标的几种情况:
     * 1. 如果当前点击的下标是0, 直接把所有的下标清空
     * 2. 如果当前点击的下标不是0, 则把当前下标之前的下标 全部填充
     * */
    subIndex.value = index;
    clearSub();
    if (index !== 0) {
      subfixItemsInner.value.forEach((elm, i) => (i < index) && (elm.style.width = '100%'));
    }
  }

  // 倒计时
  const countDown = (shift?: boolean) => {
    /**
     * @param {Boolean} shift 是否切换, 如果是切换的话 直接停止定时器
    */
    // 60px  3s
    if (shift) return clearInterval(countDownTimer.value);
    let offsetWidth = 0;
    countDownTimer.value = setInterval(() => {
      // 给下标加动画
      const subfixInnerElm = subfixItemsInner.value[subIndex.value];
      offsetWidth += 1;
      (subfixInnerElm as HTMLElement).style.width = offsetWidth + '%';
      // 如果下标的宽度到了100%就切换
      if (offsetWidth >= 100) {
        subIndex.value += 1;
        offsetWidth = 0;
        imgRoll();
        // 到了最后一张图片 清空subfixInner的width
        if (subIndex.value >= props.images.length) {
          subIndex.value = 0;
          clearSub();
        }
      }
    }, 50);
  }

  // 主动切换(下标)
  const shift = (event: MouseEvent | number, icon: boolean) => {
    // 当点击切换的时候, 要从当前的图片切换到点击的图片
    const oldSubIndex = subIndex.value;
    const index: any = icon ? event : Number(((event as MouseEvent).target as HTMLElement).dataset.key);
    
    // 如果要切换的图片索引和当前的图片索引一致, 则不需要做任何事情
    if (oldSubIndex === index) return;
    // 1.停止定时器
    countDown(true);
    // 2.清空下标, 并且填充当前index之前的所有下标
    shiftSub(index);

    // 要切换的图片
    const shiftImg = imgMap.value[index];
    // 当前的元素(第一个元素)
    const firstNode = (bannerElm.value as any as HTMLElement).children[0];

    // @ts-ignore
    if (!firstNode.src.includes(shiftImg)) {
      // 不相同的话 要从当前的图片切换到切换的图片, 相同的话 不用动
      // 如果要切换的图片是当前图片的下一个, 那就直接切换, 不用改变图片的位置(通过路径找索引)
      var shiftIndex = props.images.indexOf(shiftImg);  // 获取切换图片的索引
      if ((oldSubIndex + 1) == shiftIndex) {
        // 直接切换即可
        imgRoll();
      }
      // 不是切换到下一个
      else {
        // 如果要切换的图片 不是当前图片的下一个 那就要改变一下图片的位置
        const beforeImgs: Array<any> = [];
        const currentImg = props.images[oldSubIndex];
        // @ts-ignore
        [...bannerElm.value.children].forEach((el, i) => {
          // 不是切换的照片, 也不是当前的照片
          if (!el.src.includes(shiftImg.slice(1)) && !el.src.includes(currentImg.slice(1))) {
            var rmNode = (bannerElm.value as any as HTMLElement).removeChild(el);
            beforeImgs.push(rmNode);
          }
        });
        imgRoll(beforeImgs);
      }
    }
    // 开启定时器
    countDown();
  }

  // 主动切换(icon), 直接调用下标切换即可
  const iconShift = (flag: ItemType) => {
    if (flag === 'left') {
      const index = subIndex.value - 1;
      // 1.如果当前的图片索引-1小于0, 则切换到最后一张图片
      index < 0 ? shift(props.images.length - 1, true) : shift(index, true);
    } else {
      const index = subIndex.value + 1;
      index >= props.images.length ? shift(0, true) : shift(index, true);
    }
  }

  return {
    imgMap,
    iconShift,
    imgRoll,
    clearSub,
    shiftSub,
    countDown,
    shift,
    receiveBannerBox,
    receiveSubfixItem,
    receiveSubfixItemInner
  }
}

export { useCarousel }
